
`include "common_header.verilog"

//  *************************************************************************
//   File : pcs_tx_state_mc.v
//  *************************************************************************
//   This program is controlled by a written license agreement.
//   Unauthorized Reproduction or Use is Expressly Prohibited. 
// 
//  Copyright (c) 2005 Morethanip GmbH
//  info@morethanip.com
//  *************************************************************************
//  Version: $Id: xgxs_rx_cntl_col.v,v 1.4 2009/02/27 12:55:41 mr Exp $ 
//  Author : Muhammad Anisur Rahman
//  *************************************************************************
//  Description:
// 
//  PCS receive control for single column(Four Lans) 
//  and PCS code-group to XGMII character Mapping 
// 
//  *************************************************************************

module xgxs_rx_cntl_col (

   reset,
   clk,
  `ifdef USE_CLK_ENA
   clk_ena,
  `endif   
   ln_align,
   deskew_rxd,
   deskew_rxc,
   rxd,
   rxc);

input   reset;                  //  Active High Reset
input   clk;                    //  156.25MHz Receive Clock 
`ifdef USE_CLK_ENA
input   clk_ena;
`endif 
input   ln_align;               //  Lane Alignment Done
input   [31:0] deskew_rxd;      //  Decoded Data 
input   [3:0] deskew_rxc;       //  Special Character Indication
output  [31:0] rxd;             //  Receive Data
output  [3:0] rxc;              //  Receive Control 

reg     [31:0] rxd; 
reg     [3:0] rxc; 

wire    [3:0] xgmii_idlc;       // Control signal for idle
wire    xgmii_seqc;             // control signal for sequence
wire    xgmii_startc;           // control signal for start code group
wire    [3:0] xgmii_termc;      // Control signal for terminate
wire    [3:0] xgmii_reserved;  // Other reserved control code to be accepted

// Control signals extracted from the Decoded data
// -----------------------------------------------

assign xgmii_idlc[0] = deskew_rxc[0] == 1'b 1 & (deskew_rxd[7:0] == 8'h 1C | 
      deskew_rxd[7:0] == 8'h 7C | deskew_rxd[7:0] == 8'h BC) ? 1'b 1 : 1'b 0; 
assign xgmii_idlc[1] = deskew_rxc[1] == 1'b 1 & (deskew_rxd[15:8] == 8'h 1C | 
      deskew_rxd[15:8] == 8'h 7C | deskew_rxd[15:8] == 8'h BC) ? 1'b 1 : 1'b 0; 
assign xgmii_idlc[2] = deskew_rxc[2] == 1'b 1 & (deskew_rxd[23:16] == 8'h 1C | 
      deskew_rxd[23:16] == 8'h 7C | deskew_rxd[23:16] == 8'h BC) ? 1'b 1 : 1'b 0; 
assign xgmii_idlc[3] = deskew_rxc[3] == 1'b 1 & (deskew_rxd[31:24] == 8'h 1C | 
      deskew_rxd[31:24] == 8'h 7C | deskew_rxd[31:24] == 8'h BC) ? 1'b 1 : 1'b 0; 
assign xgmii_seqc = deskew_rxc[0] == 1'b 1 & (deskew_rxd[7:0] == 8'h 9C | deskew_rxd[7:0] == 8'h 5C) ? 1'b 1 : 1'b 0; 
assign xgmii_startc = deskew_rxc[0] == 1'b 1 & deskew_rxd[7:0] == 8'h FB ? 1'b 1 : 1'b 0; 
assign xgmii_termc[0] = deskew_rxc[0] == 1'b 1 & deskew_rxd[7:0] == 8'h FD ? 1'b 1 : 1'b 0; 
assign xgmii_termc[1] = deskew_rxc[1] == 1'b 1 & deskew_rxd[15:8] == 8'h FD ? 1'b 1 : 1'b 0; 
assign xgmii_termc[2] = deskew_rxc[2] == 1'b 1 & deskew_rxd[23:16] == 8'h FD ? 1'b 1 : 1'b 0; 
assign xgmii_termc[3] = deskew_rxc[3] == 1'b 1 & deskew_rxd[31:24] == 8'h FD ? 1'b 1 : 1'b 0; 

assign xgmii_reserved[0] = deskew_rxc[0] == 1'b 1 & (deskew_rxd[7:0] == 8'h 3C | 
      deskew_rxd[7:0] == 8'h DC | deskew_rxd[7:0] == 8'h FC | deskew_rxd[7:0] == 8'h F7) ? 1'b 1 : 1'b 0;
assign xgmii_reserved[1] = deskew_rxc[1] == 1'b 1 & (deskew_rxd[15:8] == 8'h 3C | 
      deskew_rxd[15:8] == 8'h DC | deskew_rxd[15:8] == 8'h FC | deskew_rxd[15:8] == 8'h F7) ? 1'b 1 : 1'b 0;
assign xgmii_reserved[2] = deskew_rxc[2] == 1'b 1 & (deskew_rxd[23:16] == 8'h 3C | 
      deskew_rxd[23:16] == 8'h DC | deskew_rxd[23:16] == 8'h FC | deskew_rxd[23:16] == 8'h F7) ? 1'b 1 : 1'b 0;
assign xgmii_reserved[3] = deskew_rxc[3] == 1'b 1 & (deskew_rxd[31:24] == 8'h 3C | 
      deskew_rxd[31:24] == 8'h DC | deskew_rxd[31:24] == 8'h FC | deskew_rxd[31:24] == 8'h F7) ? 1'b 1 : 1'b 0;

always @(posedge reset or posedge clk)
   begin : process_1
   if (reset == 1'b 1)
      begin
      rxd <= 32'h 07070707;   
      rxc <= 4'b 1111;   
      end
   else
      begin
      
         `ifdef USE_CLK_ENA
            if(clk_ena == 1'b 1)
            begin
         `endif      
      
              if (ln_align == 1'b 1)
                 begin
                 rxc <= deskew_rxc;   // control signals remain unchanged for PCS 
        
         // code-group to XGMII character Mapping
         // -------------------------------------
           
           // Lane 0 : PCS code-group to XGMII character Mapping
           // --------------------------------------------------
           
                 if (deskew_rxc[0] == 1'b 0 | xgmii_seqc == 1'b 1 | 
              xgmii_startc == 1'b 1 | xgmii_termc[0] == 1'b 1 | xgmii_reserved[0] == 1'b 1)
                    begin
                    rxd[7:0] <= deskew_rxd[7:0];   
                    end
                 else if (xgmii_idlc[0] == 1'b 1 )
                    begin
                    rxd[7:0] <= 8'h 07;   
                    end
                 else
                    begin
                    rxd[7:0] <= 8'h FE;   
                    end
        
           // Lane 1 : PCS code-group to XGMII character Mapping
           // --------------------------------------------------
           
                 if (deskew_rxc[1] == 1'b 0 | xgmii_termc[1] == 1'b 1 | xgmii_reserved[1] == 1'b 1)
                    begin
                    rxd[15:8] <= deskew_rxd[15:8];   
                    end
                 else if (xgmii_idlc[1] == 1'b 1 )
                    begin
                    rxd[15:8] <= 8'h 07;   
                    end
                 else
                    begin
                    rxd[15:8] <= 8'h FE;   
                    end
        
           // Lane 2 : PCS code-group to XGMII character Mapping
           // --------------------------------------------------
           
                 if (deskew_rxc[2] == 1'b 0 | xgmii_termc[2] == 1'b 1 | xgmii_reserved[2] == 1'b 1)
                    begin
                    rxd[23:16] <= deskew_rxd[23:16];   
                    end
                 else if (xgmii_idlc[2] == 1'b 1 )
                    begin
                    rxd[23:16] <= 8'h 07;   
                    end
                 else
                    begin
                    rxd[23:16] <= 8'h FE;   
                    end
        
           // Lane 3 : PCS code-group to XGMII character Mapping
           // --------------------------------------------------
           
                 if (deskew_rxc[3] == 1'b 0 | xgmii_termc[3] == 1'b 1 | xgmii_reserved[3] == 1'b 1)
                    begin
                    rxd[31:24] <= deskew_rxd[31:24];   
                    end
                 else if (xgmii_idlc[3] == 1'b 1 )
                    begin
                    rxd[31:24] <= 8'h 07;   
                    end
                 else
                    begin
                    rxd[31:24] <= 8'h FE;   
                    end
                 end
              else
                 begin
                 rxd[31:0] <= 32'h 0100009C;   
                 rxc <= 4'b 0001;   
                 end
      
         `ifdef USE_CLK_ENA
            end
         `endif      
      
      end
   end

endmodule // module xgxs_rx_cntl_col